##
## Comunication functions/commands

package Purl::Commands::basic;
use strict;
use constant NONE => -1;
use Purl::Config;
use Purl::Template;

sub import {
    Purl::Commands::register(
        name                  => "say",
        aliases               => '"',
        subRef                => \&Purl::Commands::basic::cmd_say,
        shortCommandException => 1
    );
    Purl::Commands::register(
        name                  => "emote",
        subRef                => \&Purl::Commands::basic::cmd_emote,
        aliases               => "; : pose",
        shortCommandException => 1
    );
    Purl::Commands::register(
        name                  => "whisper",
        aliases               => '. w',
        subRef                => \&Purl::Commands::basic::cmd_whisper,
        shortCommandException => 1
    );
    Purl::Commands::register(
        name                  => "IDLE",
        subRef                => \&Purl::Commands::basic::cmd_noop,
        aliases               => 'noop @@',
        shortCommandException => 1
    );
    Purl::Commands::register(
        name    => '@wall',
        authRef => \&Purl::tests::isWizard,
        subRef  => \&Purl::Commands::basic::wall,
    );
    Purl::Commands::register(
        name   => '@emit',
        subRef => \&Purl::Commands::basic::cmd_emit
    );
    Purl::Commands::register(
        name   => "page",
        subRef => \&Purl::Commands::basic::page
    );
    Purl::Commands::register(
        name    => "testhook",
        subRef  => \&Purl::Commands::basic::cmd_testhook,
        aliases => "testing test",
    );
    Purl::Commands::register(
        name   => "think",
        subRef => \&Purl::Commands::basic::think
    );
    Purl::Commands::register(
        name   => "xyzzy",
        subRef => \&Purl::Commands::basic::xyzzy
    );
    Purl::Commands::register(
        name   => '@version',
        subRef => \&Purl::Commands::basic::cmd_version,
    );
    Purl::Commands::register(
        name   => 'QUIT',
        subRef => \&Purl::Commands::basic::cmd_quit,
    );
    Purl::Commands::register(
        name   => 'LOGOUT',
        subRef => \&Purl::Commands::basic::cmd_logout,    
    );
}
### Basic Utility Functions
sub cmd_testhook {
    print "Test Hook triggered\n";
    my %args = @_;
    print "\n";
    my ( $package, $file, $line, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 )
        = caller(1);
    print
        "Caller - P:$package, F:$file, L:$line,$p3, $p4, $p5, $p6, $p7,$p8, $p9, $p10\n";
    foreach my $arg ( keys %args ) {
        print "$arg : $args{$arg}\n";
    }
}

sub cmd_whisper {
    my %args = @_;
    my ($id);
    ( $args{target}, $args{text} ) = split( " ", $args{text}, 2 );
    if ( substr( $args{target}, 0, 1 ) eq "." ) {
        Purl::comm::sendTextToPlayer(
            target => $args{actor},
            text   =>
                "Sorry, support for .. has been removed. Please use ' instead of .. as this makes the .name whisper shortcut safe to use."
        );
        return;
    }

#  print "DEBUG - cmd_whisper - actor=$args{actor}, target=$args{target}, text=$args{text}\n";
    if ( ( $args{target} eq "" ) || ( $args{text} eq "" ) ) {
        Purl::comm::sendTextToPlayer(
            target => $args{actor},
            text   =>
                "Syntax: .person message, .person,person,person message, or whisper person = message"
        );
        return;
    }
    my (@ids) = Purl::database::getIdsSpokenTo(
        actor  => $args{actor},
        target => $args{target}
    );
    if ( !int(@ids) ) {

        #     print "DEBUG: No one to whisper to.\n";

        # Nobody passed muster
        return;
    }
    my ( $names, $lnames );
    $names = " ";
    for ( my $i = 0; ( $i < int(@ids) ); $i++ ) {
        if ( $i > 0 ) {
            if ( $i == ( int(@ids) - 1 ) ) {
                $names .= " and ";
            }
            else {
                $names .= ", ";
            }
        }
        $names .= $main::objects[ $ids[$i] ]{"name"};
    }
    $names .= ".";
    my (%ids);
    for $id (@ids) {
        next if ( exists( $ids{$id} ) );
        $ids{$id} = 1;
        my ($n) = $main::objects[$id]{"name"};
        $lnames = $names;
        $lnames =~ s/ $n([,\.\ ])/ you$1/;
        Purl::comm::sendTextToPlayer(
            target => $id,
            text   => $main::objects[ $args{actor} ]{"name"}
                . " whispers, \""
                . $args{text}
                . "\" to$lnames"
        );
    }
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   => "You whisper \"" . $args{text} . "\" to$names"
    );
}

sub think {
    my %args = @_;
    $args{text} =~ s/^\s+//;
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   => Purl::filter::substitute( $args{actor}, $args{text} )
    );
}

sub cmd_say {
    my %args = @_;
    $args{text} =~ s/^\s+//;
    if ( $args{target} ne "" ) {
        my (@ids)
            = Purl::database::getIdsSpokenTo( $args{actor}, $args{target} );
        return if ( !int(@ids) );
        my ( $names, $i );
        for ( $i = 0; ( $i < int(@ids) ); $i++ ) {
            if ( $i > 0 ) {
                if ( $i == ( int(@ids) - 1 ) ) {
                    $names .= " and ";
                }
                else {
                    $names .= ", ";
                }
            }
            $names .= $main::objects[ $ids[$i] ]{"name"};
        }
        $args{target} = " to $names";
    }
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   => "You say$args{target}, \""
            . Purl::filter::substitute( $args{actor}, $args{text} ) . "\""
    );
    Purl::comm::_send_text_to_contents(
        $main::objects[ $args{actor} ]{"location"},
        $args{actor},
        $main::objects[ $args{actor} ]{"name"}
            . " says$args{target}, \""
            . Purl::filter::substitute( $args{actor}, $args{text} ) . "\""
    );
}

sub wall {
    my %args = @_;
    $args{text} =~ s/^\s+//;
    foreach my $o (@main::objects) {
        Purl::comm::sendTextToPlayer(
            target => $o->{"id"},
            text   => $main::objects[ $args{actor} ]{"name"}
                . " yells, \""
                . Purl::filter::substitute( $args{actor}, $args{text} ) . "\""
            )
            if ( $o->{"type"} == $main::player );
    }
}

sub cmd_emit {
    my %args = @_;
    $args{text} =~ s/^\s+//;
    if ( !config("allowemit") ) {
        Purl::comm::sendTextToPlayer(
            target => $args{actor},
            text   => "Sorry, that command is forbidden."
        );
        return;
    }
    if ( $args{text} eq "" ) {
        Purl::comm::sendTextToPlayer(
            target => $args{actor},
            text   => "Syntax: \@emit message"
        );
    }
    else {
        Purl::comm::_send_text_to_contents(
            $main::objects[ $args{actor} ]{"location"},
            NONE,
            Purl::filter::substitute( $args{actor}, $args{text} ),
            $main::objects[ $args{actor} ]{"name"}
        );
    }
}

sub xyzzy {
    my %args = @_;
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   => ">>Foof!<<"
    );
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text => "You are inside a building, a well house for a large spring."
    );
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   => "There are some keys on the ground here."
    );
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   => "There is a shiny brass lamp nearby."
    );
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   => "There is food here."
    );
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   => "There is a bottle of water here."
    );
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   =>
            "You are able to take in your surroundings for a few seconds before a second >>Foof!<< deposits you back in your previous location. Apparently your wimpy wizardly powers don't enable you to stay in that distant land for long."
    );
}

sub cmd_emote {
    my %args = @_;
    $args{text} =~ s/^\s+//;
    unless ( $args{command} eq ";" ) {
        $args{text} = " " . $args{text};
    }
    Purl::comm::_send_text_to_contents(
        $main::objects[ $args{actor} ]{"location"},
        NONE,
        $main::objects[ $args{actor} ]{"name"}
            . Purl::filter::substitute( $args{actor}, $args{text} )
    );
}

sub page {
    my %args = @_;
    ( $args{target}, $args{text} ) = split( " ", $args{text}, 2 );

#   print    "DEBUG: page - me=$args{actor}, arg1=$args{target}, arg2=$args{text}\n";
    my $id;
    if ( substr( $args{target}, 0, 1 ) ne "#" ) {
        my $n = $args{target};
        $n =~ tr/A-Z/a-z/;
        if ( !exists( $main::playerIds{$n} ) ) {
            Purl::comm::sendTextToPlayer(
                target => $args{actor},
                text   => "There is no such player."
            );
            return;
        }
        $id = $main::playerIds{$n};
    }
    else {
        $id = substr( $args{arget}, 1 );
        $id = &main::idBounds($id);
    }
    if ( $id == NONE ) {
        Purl::comm::sendTextToPlayer(
            target => $args{actor},
            text   => "That is not a valid player. 1"
        );
        return;
    }
    if ( $main::objects[$id]{"type"} != $main::player ) {
        Purl::comm::sendTextToPlayer(
            target => $args{actor},
            text   => "That is not a valid player. 2"
        );
        return;
    }
    if ( $main::objects[$id]{"activeFd"} == NONE ) {
        Purl::comm::sendTextToPlayer(
            target => $args{actor},
            text   => "That player is not logged in."
        );
        return;
    }
    if ( $args{text} eq "" ) {
        Purl::comm::sendTextToPlayer(
            target => $id,
            text   => $main::objects[ $args{actor} ]{"name"}
                . " is looking for you in "
                . $main::objects[ $main::objects[ $args{actor} ]{"location"} ]
                {"name"} . "."
        );
        Purl::comm::sendTextToPlayer(
            target => $args{actor},
            text   => "You paged " . $main::objects[$id]{"name"} . "."
        );
    }
    else {
        Purl::comm::sendTextToPlayer(
            target => $id,
            text   => $main::objects[ $args{actor} ]{"name"}
                . " pages: "
                . $args{text}
        );
        Purl::comm::sendTextToPlayer(
            target => $args{actor},
            text   => "You paged "
                . $main::objects[$id]{"name"} . ": "
                . $args{text}
        );
    }
}

sub cmd_version {
    my %args = @_;
    Purl::comm::sendTextToPlayer(
        target => $args{actor},
        text   => "PurlMUSH version $Purl::VERSION\n"
    );

    return;

}

sub cmd_quit {
    my %args = @_;
    Purl::Network::closePlayerID( $args{actor} );
    return;
}

sub cmd_logout {
    my %args = @_;
    Purl::Network::logoutPlayerID( $args{actor} );
    return;
}

sub cmd_noop {

    # No operations where harmed in the creations of this command
    return;
}

1;
